using System.Collections.Generic;
using Gameplay.PVE.Config;
using Gameplay.PVE.Entity;
using Gameplay.PVE.Utils;
using UnityEngine;

namespace Gameplay.PVE.Skill
{
    public class Wave : SkillBullet
    {
        private float interval = 0.2f;
        private float width;
        private float height;

        private List<GameObject> testWaveObjects = new List<GameObject>();

        private bool isGround = false;
        public override void Initialize(PveSkillBulletConfig config, PveSkillConfig skillConfig,SkillBase skill, Vector3 startPosition, Vector3 offset, Vector3 angle,
            UnitBase source)
        {
            base.Initialize(config, skillConfig,skill, startPosition, offset, angle, source);
            config.director_args.TryGetValue("width", out width);
            config.director_args.TryGetValue("height", out height);
            if (height == 0)
            {
                height = config.max_distance;
            }
            destroyTime = height / config.speed;
            for (int i = 0; i < testWaveObjects.Count; i++)
            {
                if (testWaveObjects[i] != null)
                {
                    GameObject.Destroy(testWaveObjects[i]);   
                }
            }
            testWaveObjects.Clear();
            isGround = false;
            if (config.director_args.ContainsKey("ground"))
            {
                var verticalOffset = offset;
                verticalOffset.y = 0;
                var offsetApplyRatio = Random.Range(0, 0.8f);
                
                targetPosition = targetPosition + verticalOffset * offsetApplyRatio;
                //targetPosition += PveUtils.GetRandomVector3(new Vector3(-0.3f, 0, -0.3f), new Vector3(0.3f, 0, 0.3f));
                speed = (targetPosition - bullet.transform.position).normalized * speedValue;
                destroyTime = Vector3.Distance(targetPosition,bullet.transform.position) / speedValue;
                bullet.transform.forward = speed;
                isGround = true;
            }
        }
        
        protected override void UpdatePosition(float deltaTime)
        {
            if (!isGround)
            {
                base.UpdatePosition(deltaTime);
            }
            else
            {
                if (!IsDisposed)
                {
                    Vector3 currentPosition = lastPosition + speed * deltaTime;
                    bullet.transform.position = currentPosition;
                    lastPosition = currentPosition;
                    if (isGround && bullet.transform.position.y <= 0)
                    {
                        bullet.transform.position =
                            targetPosition;
                        bullet.transform.forward = new Vector3(bullet.transform.forward.x,0,bullet.transform.forward.z);
                        Dispose();
                    }
                }
            }
        }

        public override void Update(float deltaTime)
        {
            if (IsDisposed)
            {
                return;
            }
            lastTime = TimeManager.logicTime;
            CheckHit(lastPosition, speed, speedValue * deltaTime,true);
            UpdatePosition(deltaTime);
            UpdateTrail();
            if (config.damage_type == 4 && bullet.transform.position.y <= 0)
            {
                Explosive();
            }

            if (bullet != null && isGround && bullet.transform.position.y <= 0)
            {
                bullet.transform.position = new Vector3(bullet.transform.position.x,0,bullet.transform.position.z);
                Dispose();
            }
        }

        private void Explosive()
        {
            var pos = bullet.transform.position;
            PveEffectManager.Instance.PlayEffect(10,new Vector3(pos.x,0,pos.z),Vector3.forward);
            PveCameraManager.Instance.Shake(0.3f);
            Dispose();
        }

        public override void Dispose(bool isForceDestroy = false)
        {
            base.Dispose(isForceDestroy);
            for (int i = 0; i < testWaveObjects.Count; i++)
            {
                if (testWaveObjects[i] != null)
                {
                    GameObject.Destroy(testWaveObjects[i]);   
                }
            }
            testWaveObjects.Clear();
        }

        protected override void CheckHit(Vector3 startPosition, Vector3 direction, float length, bool considerObstacle = false)
        {
            int index = 0;
            Quaternion q = Quaternion.AngleAxis(PveUtils.GetAngle(Vector3.forward,direction), Vector3.up);
            for (float start = -width / 2; start <= width / 2; start += interval)
            {
                if (IsDisposed)
                {
                    return;
                }
                var offset = new Vector3(start,0,0);
                offset = q * offset;
                var position = startPosition + offset;
                position.y = 0.1f;
                if (PveGlobalVlues.ShowWaveHitArea)
                {
                    if (testWaveObjects.Count <= index)
                    {
                        testWaveObjects.Add(GameObject.CreatePrimitive(PrimitiveType.Cube));
                    }
                    testWaveObjects[index].transform.position = position;
                }
                base.CheckHit(position, direction, length, considerObstacle);
                index++;
            }
        }
    }
}